package org.biz.util;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.biz.common.ExportField;

import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

public class ExcelUtils {

    /**
     *
     * @param data 导出列表
     * @param clazz 导出实体
     * @param response
     * @param <T>
     * @throws IOException
     */
    public static <T> void exportToExcel(List<T> data, Class<T> clazz,String fileName, HttpServletResponse response) throws IOException {
        Workbook workbook = new XSSFWorkbook();  // 创建工作簿
        Sheet sheet = workbook.createSheet("Sheet1");  // 创建工作表

        // 获取所有字段并筛选出带有 @ExportField 注解的字段
        Field[] fields = clazz.getDeclaredFields();
        List<Field> exportFields = new ArrayList<>();

        // 选择带有 @ExportField 注解的字段
        for (Field field : fields) {
            if (field.isAnnotationPresent(ExportField.class)) {
                exportFields.add(field);
            }
        }

        // 创建标题行
        Row headerRow = sheet.createRow(0);

        // 创建标题单元格样式
        CellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setWrapText(true); // 自动换行
        headerStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中
        headerStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中

        for (int i = 0; i < exportFields.size(); i++) {
            Field field = exportFields.get(i);
            field.setAccessible(true); // 允许访问私有字段
            ExportField annotation = field.getAnnotation(ExportField.class);
            String header = annotation.name().isEmpty() ? field.getName() : annotation.name();  // 获取注解中的表头名称
            Cell headerCell = headerRow.createCell(i);
            headerCell.setCellValue(header);  // 设置标题为字段名称

            headerCell.setCellStyle(headerStyle); // 应用样式

            // 设置列宽，若注解中指定了 width 则使用该值
            int width = annotation.width();
            if (width != -1) {
                sheet.setColumnWidth(i, width * 256);
            }
        }

        // 填充数据行
        int rowNum = 1;
        for (T obj : data) {
            Row row = sheet.createRow(rowNum++);
            for (int colNum = 0; colNum < exportFields.size(); colNum++) {
                Field field = exportFields.get(colNum);
                field.setAccessible(true);
                try {
                    Object value = field.get(obj);  // 获取字段值
                    Cell cell = row.createCell(colNum);
                    if (value != null) {
                        cell.setCellValue(value.toString());  // 设置单元格内容
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }



        // 设置响应头，通知浏览器下载
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode(fileName,"UTF-8"));

        // 将 Excel 文件写入到输出流
        try (OutputStream out = response.getOutputStream()) {
            workbook.write(out);
        } finally {
            workbook.close();
        }
    }
}
